package com.sino.operation.service.manage;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sino.operation.commons.commonEnum.ChargeInfoEnum;
import com.sino.operation.entity.BizAccountmanageInfo;
import com.sino.operation.entity.BizTranslist;
import com.sino.operation.peripheral.esc.request.core.EscAccountTest;
import com.sino.operation.peripheral.esc.request.core.param.Core_4010_Listnm01Info_Param;
import com.sino.operation.peripheral.esc.request.core.param.Core_4010_ListnmInfo_param;
import com.sino.operation.peripheral.esc.request.manage.param.Manage_1005_Param;
import com.sino.operation.peripheral.esc.response.EscResSysHead;
import com.sino.operation.peripheral.esc.response.EscRet;
import com.sino.operation.peripheral.esc.response.core.EscCoreDto;
import com.sino.operation.peripheral.esc.response.core.body.EscResBody2110;
import com.sino.operation.peripheral.esc.response.core.body.EscResBodyManage1005;
import com.sino.operation.service.business.ObtainEscCoreParamService;
import com.sino.operation.util.EscBodyMapTestUtil;
import com.sino.operation.util.RestTemplateUtils;
import com.sino.operation.util.TimeUtil;
import com.sino.operation.util.UrlUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName ManageService
 * @Description 账管业务类
 * @Author 北陈
 * @Date 2021/11/8 18:07
 * @Version 1.0
 */
@Slf4j
@Service
public class ManageService {


    @Autowired
    private ObtainEscCoreParamService obtainEscCoreParamService;

    @Autowired
    private UrlUtil urlUtil;

    @Autowired
    private RestTemplateUtils restTemplateUtils;


    /**
     * @Description: ${活期开户账管报备}
     * param [mapPost2110, mapPostManage, escResBody2110, bizTranslist, bizAccountmanageInfo]
     * return void
     * author 北陈
     * date 2021/11/8 18:20
    */
    public void openAccountReport(Map<String,Object> mapPost2110, Map<String,Object> mapPostManage, EscResBody2110 escResBody2110, BizTranslist bizTranslist, BizAccountmanageInfo bizAccountmanageInfo){
        String journalNo = bizTranslist.getJournalNo();
        String imageId = bizTranslist.getImageId();
        EscAccountTest escParam = obtainEscCoreParamService.getEscCoreParam(journalNo, "1005");
        String accountManageUrl = urlUtil.getAccountManage("1005");
        String clientNo = bizTranslist.getClientNo();
        Map<String, Object> mapPost = new HashMap<>(16);
        mapPost.put("TRAN_CODE", "ZDBS01");//交易码
        mapPost.put("MSG_TYPE", "00");//报文类型
        mapPost.put("CHANNEL_TYPE", "01");//集中作业渠道
        Map<String, Object> sys = new HashMap<>(16);

        Map map1005Params = this.manageReportNewAccount(mapPost2110);


        sys.put("acctNo", clientNo);//账号
        sys.put("customerNo", clientNo);//客户号
        sys.put("acctType", mapPost2110.get("acct_clasf"));//账户性质
        sys.put("organCode", mapPost2110.get("open_acct_org"));//核心机构号
        sys.put("acctCreateDate", escResBody2110.getTxnDt8());//开户日期
        sys.put("effectiveDate", mapPost2110.get("acct_vld_prd"));//账户有效期
        sys.put("accountKey", mapPostManage.get("basic_acct_open_per"));//基本开户许可证号
        sys.put("customerNo", mapPost2110.get("atht_file_catg2"));//证明文件2种类

        //地址信息
        Object listnm01 = mapPostManage.get("listnm01");
        if (ObjectUtil.isNotNull(listnm01)) {
            List<Map<String, Object>> listNm01 = (List<Map<String, Object>>) listnm01;
            for (int i = 0; i < listNm01.size(); i++) {
                Map<String, Object> map1 = listNm01.get(i);
                if ("210".equals(map1.get("addr_tp"))) {
                    sys.put("regProvince", map1.get("prov_or_state"));//省份code
                    sys.put("regCity", map1.get("city"));//城市code
                    sys.put("regArea", map1.get("county"));//城区code
                    sys.put("regAddress", map1.get("remks_info"));//详细地址
                    sys.put("regAreaCode", map1.get("rgon_code_num"));//注册弟弟去代码
                    sys.put("regFullAddress", map1.get("addr_cntnt"));//完整注册地址
                    sys.put("basicAcctRegArea", map1.get("rgon_code_num"));//基本户注册地地区代码
                    sys.put("zipcode", map1.get("pstcd"));
                } else if ("220".equals(map1.get("addr_tp"))) {
                    sys.put("workProvince", map1.get("prov_or_state"));//办公地址身份code
                    sys.put("workCity", map1.get("city"));//办公地址城市code
                    sys.put("workArea", map1.get("county"));//办公地址城区code
                    sys.put("workAddress", map1.get("remks_info"));//办公地址详细地址
                }
            }
        }

        //对公电子信息
        Object listnm02 = mapPostManage.get("listnm02");
        if (ObjectUtil.isNotNull(listnm02)) {
            List<Map<String, Object>> listNm02 = (List<Map<String, Object>>) listnm02;
            for (int i = 0; i < listNm02.size(); i++) {
                Map<String, Object> map1 = listNm02.get(i);
                //注册地址
                if ("13".equals(map1.get("cntct_info"))) {
                    sys.put("telephone", map1.get("cntct_tel"));//联系电话
                }
            }
        }
        //行业归属
        sys.put("industryCode", mapPostManage.get("idsty_class") == null ? null : ((String) mapPostManage.get("idsty_class")).substring(0, 1));
        sys.put("regOffice", "");//登记部门
        sys.put("regType", "");//登记注册类型
        sys.put("regNo", "");//登记注册编号
        sys.put("businessScope", mapPostManage.get("oprn_scope"));//经营（业务）范围
        sys.put("businessScopeEccs", "");//经营（业务）范围，报送信用代码证
        sys.put("corpScale", mapPostManage.get("entp_scale"));//企业规模
        sys.put("regCurrencyType", mapPostManage.get("rgstn_cptl_ccy"));//注册资金币别
        Object cptl = mapPostManage.get("rgstn_cptl");
        String rgstn = "";
        if (ObjectUtil.isNotNull(cptl)) {
            rgstn = (String) cptl;
            BigDecimal convert = Convert.convert(BigDecimal.class, rgstn);
            if (convert.compareTo(new BigDecimal(0)) == 0) {
                rgstn = "";
            }
        }
        sys.put("registeredCapital", rgstn);//注册资金
        //注册资金币种、注册资金不为空时，为表明注册资金送0，否则送1
        if (StringUtils.isNotEmpty((String) sys.get("regCurrencyType"))) {
            sys.put("isIdentification", "1");
        } else {
            sys.put("isIdentification", "0");
        }
        sys.put("economyType", "");//经济类型
        sys.put("legalType", mapPostManage.get("corpt_rprtv_class"));//法定代表人类型
        sys.put("legalName", mapPostManage.get("corpt_rprtv_nm"));//法人姓名
        sys.put("legalIdcardType", mapPostManage.get("corpt_rprtv_docs_catg"));//法人证件类型
        sys.put("legalIdcardNo", mapPostManage.get("corpt_rprtv_docs_num"));//法人证件号码
        sys.put("legalTelephone", mapPostManage.get("corpt_rprtv_tel_num"));//法人电话号码
        sys.put("legalIdcardDue", mapPostManage.get("lgl_pern_docs_vld_dt"));//法人证件到期日
        sys.put("noTaxProve", "");//无需办理税务登记证的文件或税务机关出具的证明
        sys.put("stateTaxRegNo", mapPostManage.get("org_tax_pymt_num"));//纳税人识别号（国税）
        sys.put("taxRegNo", mapPostManage.get("othr_rlzd_remks_info"));//纳税人识别号（地税）
        sys.put("orgType", "");//组织机构类别
        sys.put("orgTypeDetail", "");//组织机构类别细分
        sys.put("orgCode", mapPostManage.get("org_org_code"));//组织机构代码
        sys.put("financeTelephone", "");//财务主管电话
        sys.put("parAccountKey", mapPostManage.get("basic_dept_acct_num"));//上级基本户开户许可证
        sys.put("parCorpName", mapPostManage.get("sprr_spvsr_corp_nm"));//上级机构名称
        sys.put("parOrgCode", mapPostManage.get("sprr_corp_org_code"));//上级组织机构代码
        sys.put("parLegalType", "");//上级法定代表人类型
        sys.put("parLegalName", mapPostManage.get("sprr_corp_lgl_pern_nm"));//上级法人姓名
        sys.put("parLegalIdcardType", mapPostManage.get("sprr_corp_docs_catg"));//上级法人证件类型
        sys.put("parLegalIdcardNo", mapPostManage.get("sprr_corp_docs_num"));//上级法人证件号码

        //经办人--取2110里面listnm列表中的值
        Object listnm = mapPost2110.get("listnm");
        if (ObjectUtil.isNotNull(listnm)) {
            List<Map<String, Object>> listNm = (List<Map<String, Object>>) listnm;
            for (int i = 0; i < listNm.size(); i++) {
                Map<String, Object> map1 = listNm.get(i);
                Object cntct_pern_catg = map1.get("cntct_pern_catg");
                if ("2".equals(cntct_pern_catg)) {
                    //如果时经办人，则赋值经办人信息
                    sys.put("operatorName", map1.get("sprr_corp_docs_num"));//经办人姓名
                    sys.put("operatorTelephone", map1.get("tel_num"));//经办人联系电话
                    sys.put("operatorIdcardNo", map1.get("docs_num"));//经办人证件号码
                    sys.put("operatorIdcardType", map1.get("docs_catg"));//经办人证件类型
                    sys.put("operatorIdcardDue", map1.get("sprr_corp_docs_num"));//经办人证件有效日期
                }
            }
        }


        sys.put("accountNameFrom", "");//账户名称构成方式
        sys.put("saccpostfix", "");//账户名称后缀
        sys.put("capitalProperty", "");//账户名称前缀
        sys.put("insideDeptName", mapPost2110.get("funds_nature"));//资金性质
        sys.put("insideLeadName", "");//内设部门名称
        sys.put("insideLeadName", "");//内设部门负责人姓名
        sys.put("insideLeadIdcardType", "");//负责人身份证件种类
        sys.put("insideLeadIdcardNo", "");//负责人身份证件编号
        sys.put("insideTelephone", "");//内设部门电话
        sys.put("insideZipcode", "");//内设部门邮政编码
        sys.put("insideAddress", "");//内设部门地址
        sys.put("fundManager", "");//资金管理人姓名
        sys.put("fundManagerIdcardType", "");//资金管理人身份证种类
        sys.put("fundManagerIdcardNo", "");//资金管理人身份证编号
        sys.put("acctCreateReason", "");//申请开户原因
        sys.put("nontmpProjectName", "");//项目部名称
        sys.put("nontmpLegalName", "");//建筑施工安装及实时负责人姓名
        sys.put("nontmpLegalIdcardType", "");//建筑施工安装及实时负责人身份证件种类
        sys.put("nontmpLegalIdcardNo", "");//建筑施工安装及实时负责人身份证件编号
        sys.put("nontmpTelephone", "");//建筑施工安装及安装 电话
        sys.put("nontmpZipcode", "");//建筑施工安装及安装 邮政编码
        sys.put("nontmpAddress", "");//建筑施工安装及安装 地址
        sys.put("imageCode", imageId);//影像流水号/批次号
        //mapPost.put("SYNC_CONTENT", sys);
        mapPost.put("SYNC_CONTENT",map1005Params);
        escParam.setMap(mapPost);

        try {
            String value = new ObjectMapper().writeValueAsString(escParam);
            log.info(TimeUtil.getStandardTime() + "发往账管系统进行报备的报文", value);
            ResponseEntity<EscCoreDto<EscResBodyManage1005>> postManage1005 = restTemplateUtils
                    .exchange(accountManageUrl, HttpMethod.POST,
                            new HttpEntity<>(escParam),
                            new ParameterizedTypeReference<EscCoreDto<EscResBodyManage1005>>() {
                            });
            EscCoreDto<EscResBodyManage1005> postManage1005Body = postManage1005.getBody();
            EscResSysHead escResSysHead = postManage1005Body.getEscResSysHead();
            String retStatus = escResSysHead.getRetStatus();
            if (ChargeInfoEnum.ACCOUNT_MANAGE_ERROR.getCode().equals(retStatus)) {

                List<EscRet> rets = escResSysHead.getRets();
                StringBuilder codeBuilder = new StringBuilder();
                StringBuilder desBuilder = new StringBuilder();
                String result = "";
                rets.forEach(escRet -> {
                    if (ObjectUtil.isNotNull(escRet)) {
                        codeBuilder.append(escRet.getRetCode());
                        desBuilder.append(escRet.getRetMsg());
                    }
                });
                log.info(TimeUtil.getStandardTime() + "-流水号" + journalNo + "\n客户账号：" + mapPost2110.get("cust_acct_num") + "发往账管系统报备失败" +
                        "\n失败原因:" + desBuilder.toString());
                bizAccountmanageInfo.setCustomUploadState("1");
                result = codeBuilder.toString() == null ? "" : codeBuilder.toString() + desBuilder.toString() == null ? "" : desBuilder.toString();
                bizAccountmanageInfo.setCustomUploadFailMessage(codeBuilder.toString() == null ? "" : codeBuilder.toString());

            }
            //推送账管报备成功
            //客户账号
            String accountKey = postManage1005Body.getEscResBody().getAccountKey();
            //查询密码
            String selectPwd = postManage1005Body.getEscResBody().getSelectPwd();
            //存款人编号,人行虚拟编号,取消核准
            String openKey = postManage1005Body.getEscResBody().getOpenKey();
            log.info(TimeUtil.getStandardTime() + "-流水号：" + journalNo + "\n客户账号：" + accountKey + "发往账管系统报备成功");
            if (StringUtils.isNotBlank(accountKey)) {
                bizAccountmanageInfo.setAccountKey(accountKey);
            }
            bizAccountmanageInfo.setOpenKey(openKey == null ? "" : openKey);
            bizAccountmanageInfo.setSelectPwd(selectPwd == null ? "" : selectPwd);
        } catch (Exception e) {
            log.error(TimeUtil.getStandardTime() + "-流水号：" + journalNo + "活期开户发往账管报备出现异常:", e.getMessage());
            bizAccountmanageInfo.setCustomUploadState("2");
            bizAccountmanageInfo.setCustomUploadFailMessage("账管报备失败");
        }
    }

    public Map manageReportNewAccount(Map<String,Object> map){
        Class<Manage_1005_Param> manage1005ParamClass = Manage_1005_Param.class;
        Map<String, Object> mapFiled = new HashMap<>(16);
        Field[] declaredFields = manage1005ParamClass.getDeclaredFields();
        for (Field field : declaredFields) {
            JsonProperty annotation = field.getAnnotation(JsonProperty.class);
            String value = annotation.value();
            ApiModelProperty annotation1 = field.getAnnotation(ApiModelProperty.class);
            String name = annotation1.name();
            mapFiled.put(value, name);
        }

        Map<String, Object> mapPostManageParam1005 = new HashMap<>(16);
        Map<String,Object> map1 = EscBodyMapTestUtil.getMap(Manage_1005_Param.class);
        for (Map.Entry<String, Object> key : map1.entrySet()){
            mapPostManageParam1005.put(key.getKey(),map.get(mapFiled.get(key.getKey())));
        }
        //客户证件信息
        Object listnm = map.get("listnm");
        if (ObjectUtil.isNotNull(listnm)){
            List<Map<String,Object>> listNm4010=(List<Map<String,Object>>)listnm;
            listNm4010.forEach(map4010ListNm->{
                if (ObjectUtil.isNotNull(map4010ListNm)){
                    mapPostManageParam1005.put("fileType",map4010ListNm.get(mapFiled.get("fileType")));
                    mapPostManageParam1005.put("fileNo",map4010ListNm.get(mapFiled.get("fileNo")));
                }
            });
        }

        //地址信息
        Object listnm01 = map.get("listnm01");
        if (ObjectUtil.isNotNull(listnm01)){
            List<Map<String,Object>> listNm014010=(List<Map<String,Object>>)listnm01;
            listNm014010.forEach(map4010ListNm01->{
                //注册地址
                if ("210".equals(map4010ListNm01.get("addr_tp"))){
                    mapPostManageParam1005.put("regProvince",map4010ListNm01.get(mapFiled.get("regProvince")));
                    mapPostManageParam1005.put("regCity",map4010ListNm01.get(mapFiled.get("regCity")));
                    mapPostManageParam1005.put("regArea",map4010ListNm01.get(mapFiled.get("regArea")));
                    mapPostManageParam1005.put("regAddress",map4010ListNm01.get(mapFiled.get("regAddress")));
                    mapPostManageParam1005.put("regFullAddress",map4010ListNm01.get(mapFiled.get("regFullAddress")));
                    mapPostManageParam1005.put("basicAcctRegArea",map4010ListNm01.get(mapFiled.get("basicAcctRegArea")));
                    mapPostManageParam1005.put("zipcode",map4010ListNm01.get(mapFiled.get("zipcode")));
                }else if ("220".equals(map4010ListNm01.get("addr_tp"))){
                    //办公地址-中文
                    mapPostManageParam1005.put("workProvince",map4010ListNm01.get(mapFiled.get("workProvince")));
                    mapPostManageParam1005.put("workCity",map4010ListNm01.get(mapFiled.get("workCity")));
                    mapPostManageParam1005.put("workArea",map4010ListNm01.get(mapFiled.get("workArea")));
                    mapPostManageParam1005.put("workAddress",map4010ListNm01.get(mapFiled.get("workAddress")));
                }
            });
        }

        //电子信息
        Object listnm02 = map.get("listnm02");
        if (ObjectUtil.isNotNull(listnm02)){
            List<Map<String,Object>> listNm024010=(List<Map<String,Object>>)listnm02;
            listNm024010.forEach(map4010ListNm02->{
                //固定电话
                if ("13".equals(map4010ListNm02.get("cntct_info"))){
                    mapPostManageParam1005.put("telephone",map4010ListNm02.get(mapFiled.get("tele")));
                }
            });
        }

        //注册资金
        Object rgstn_cptl = map.get("rgstn_cptl");
        if (ObjectUtil.isNotNull(rgstn_cptl)){
            mapPostManageParam1005.put("isIdentification","0");
        }else{
            mapPostManageParam1005.put("isIdentification","1");
        }

        return mapPostManageParam1005;
    }
}
